"""
jmespath
    下载：pip install jmespath
    官网：https://jmespath.org/
    使用方法：jmespath.search('表达式'，数据源) 
    基本表达式：. []
    进阶表达式：
        投影：如果是列表[*],字典.*
        展平：如果列表中有多个嵌套的列表，可以使用[]对其展平
        过滤：[?key==`value`]
        管道： | 继承前边的内容进行检索
"""""
import jmespath

data1 = {
    "items": [
        [
            {"name": "item1", "value": 1},
            {"name": "item2", "value": 2}
        ],
        [
            {"name": "item3", "value": 3},
            {"name": "item4", "value": 4}
        ]
    ]
}
# print(jmespath.search('items[*][*].*',data1)) # 投影
# print(jmespath.search('items[]',data1)) # 展平
# print(jmespath.search('items[*][?value==`3`]',data1)) # 过滤
# print(jmespath.search('items[*][?value==`3`]|[1]|[0]',data1)) # 管道


"""
requests库
"""""
import requests

'''json数据的post请求'''
data = {
    'url': "http://47.95.213.187:8899/adminapi/login",
    'method': "post",
    'headers': {'content-type': "application/json;charset=UTF-8"},
    'json': {"account": "admin", "pwd": "Aa123456!", "imgcode": "1"}

}

res = requests.request(**data)
# print(res.text) # 以文本格式查看响应体
# print(res.json()) # 以json格式查看响应体
# print(res.status_code) # 查看状态码
# print(res.reason) # 查看状态码的文本信息
# print(res.url) # 查看本次请求的url
# print(res.headers) # 查看响应头
# print(res.cookies) # 获取cookies
# res_time = res.elapsed.total_seconds()  # 查看响应时间，单位是s

'''get请求传参'''
data1 = {
    'url': "http://47.95.213.187:8899/api/products",
    'method': "get",
    'headers': {'content-type': "application/json;charset=UTF-8"},
    'params':{'keyword':"手机","page":1,"limit":8}
}

# print(requests.request(**data1).json())

'''表单数据的post请求'''

data2 = {
    'url': "http://httpbin.org/post",
    'method': "post",
    'data':{"name":"dengze","age":23}
}
# print(requests.request(**data2).json())

'''上传文件的请求'''
data3 = {
    'url': "http://httpbin.org/post",
    'method': "post",
    'files':{'filename':open('../requirements.txt','rb')}
}
# print(requests.request(**data3).json())



"""
pytest
    简介：pytest是一个python的测试框架，主要用于编写简单或者复杂的测试，python还有一个内置的测试框架是unittest，它俩相比，pytest更简洁，也更主流
    使用：pycharm如果想默认使用pytest，需要设置一下
    安装：pip install pytest
"""""

'''用例的编写规则'''
# 文件名：必须以test开头或结尾
# 类名：必须以Test开头，且不允许有init
# 函数名/方法名：必须以test开头

'''执行方式'''
# 执行逻辑：默认情况下，pytest会递归的查找当前目录下所有以test开始或结尾的文件，执行文件内所有的以test/Test开头的类/函数

'''执行方式一'''
# 点击箭头运行即可,仅限调试时候用

'''执行方式二'''
# 以命令的方式运行 pytets 文件名
# pytest有几个运行的参数
# -v 显示用例执行的详细信息
# -s 输出用例中可以打印的内容
# -m 只运行mark标记的用例
# -x 遇到失败的用例立即停止测试
# --collect-only 查看可以执行用例
# --maxfail 表示用例失败数等于多少时，会停止测试

'''执行方式三---pytest.ini'''
# 在项目的根目录下创建pytest.ini ,它是pytest的配置文件
# 如果项目根目录有这个文件，那么会默认识别这个文件，以这个配置文件为准去执行用例

'''执行方式四（调试用居多）'''
# 使用pytest.main()方法

'''用例管理'''
# 可以使用mark标记用例的等级
# 在pytest.ini文件中，可以自定义markers
# 用例使用就是使用装饰器@pytest.mark.名字

'''setup & teardown'''
# setup:通常是在每个测试用例执行之前的代码，用于准备测试环境，测试数据等
# teardown：通常是在每个测试执行之后的代码，用于清理数据，关闭资源等

# 模块级别
# setup_module
# teardown_module

# 类方法级别
# setup_class
# teardown_class

# class TestCase:
#     def setup_class(self):
#         pass
#     def teardown_class(self):
#         pass

# 实例方法级别
# setup_method
# setup_method

# 函数级别
# setup_function
# teardown_function

'''fixture'''
# 它是pytest自带的一个夹具，也可以实现setup，teardown的功能
# 使用方法：
#   autouse=True,用例就会自动使用这个夹具
#   放在函数/方法的（）中
#   使用装饰器@pytest.mark.usefixtures('driver')


'''conftest.py文件'''
# 这个文件的名称必须conftest.py，通常这里存放的是fixture夹具，pytest会自动识别
# conftest.py可以有多个，如果放在项目的根目录，代表的是所有测试用例都可用，如果放在子文件夹中，那么该文件夹中的测试用例可用
# 当你在conftest.py里写完夹具后，测试用例使用夹具，不需要import

'''数据驱动'''
# 使用装饰器@pytest.mark.parametrize(argnames,argvalues,indirect=Fasle,ids=None,scope=None)
# argnames:它是形参的名字
# argvalues:它是实参，也就是argnames的值
# ids:给每组数据设置标识符
# indirect:当它是True的时候，argnames的名称会被视为fixture的名称,pytest会自动调用这个fixture夹具，而不是将其作为普通的函数去传递给测试用例
# scope:仅在indirect=True有效，用于指定夹具的作用范围

'''建议传参方式'''
# 使用@pytest.mark.parametrize，indirect不是True的时候
# 编写传参夹具，直接使用夹具即可
# 使用yaml文件传参
# 使用excel文件传参

'''跳过用例'''
# @pytest.mark.skip('不想执行')
# @pytest.mark.skipif(0 < 2, reason='条件为真，跳过')

'''失败重跑'''
# 需要下载一个插件，pytest-rerunfailurs
# 使用方法一：命令行参数， --reruns <n> --reruns-delay <m>
# n代表的是失败后的最大重试次数，m是等待多少秒后进行重跑
# 使用方法二：装饰器@pytest.mark.flaky(reruns =5,reruns_delay=2)

'''控制执行顺序'''
# 需要下载一个插件pytest-ordering
# 使用方法@pytest.mark.run(order=2)
# 根据传入order值决定运行的优先级，如果传入的都是正数或者都是负数，数值越小优先级越高
# 如果正数负数同时存在，那么正数的优先级比负数高